/**
 *  Copyright 2002-2009 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package foo.bar.blog.core.domain;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.SecurityUtils;
import org.jsecurity.subject.Subject;

import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import java.util.Date;

import foo.bar.blog.core.security.UserAccountRealm;

/**
 * A JPA listener that "fill in" the creation and modification info for all domnain objects that
 * implements :-
 * <ul>
 *  <li>{@link foo.bar.blog.core.domain.CreationInfoPersistable}</li>
 *  <li>{@link foo.bar.blog.core.domain.ModificationInfoPersistable}</li>
 * </ul>
 * 
 * @author tmjee
 * @version $Date: 2009-06-27 15:56:30 +0000 (Sat, 27 Jun 2009) $ $Id$
 */
public class EntityAuditListener {

    private static final Log LOG = LogFactory.getLog(EntityAuditListener.class);


    public EntityAuditListener() {}

    @PrePersist
    public void prePersist(Object entity) {
        updateEntityAuditInfo(entity);
    }

    @PreUpdate
    public void preUpdate(Object entity) {
        updateEntityAuditInfo(entity);        
    }


    protected void updateEntityAuditInfo(Object entity) {
        if (entity instanceof Identifiable) {
            Identifiable identifiable = (Identifiable) entity;
            if (identifiable.getId() <= 0) {
                if (identifiable instanceof CreationInfoPersistable) {
                    if (currentUser() != null && (currentUser() != UserAccountRealm.ANONYMOUS_USER_ACCOUNT.getUser())) {
                        ((CreationInfoPersistable)identifiable).setCreator(currentUser());
                    }
                    ((CreationInfoPersistable)identifiable).setCreationDate(new Date(System.currentTimeMillis()));
                }
            }
            else {
                if (identifiable instanceof ModificationInfoPersistable) {
                    if (currentUser() != null && (currentUser() != UserAccountRealm.ANONYMOUS_USER_ACCOUNT.getUser())) {
                        ((ModificationInfoPersistable)identifiable).setModifier(currentUser());
                    }
                    ((ModificationInfoPersistable)identifiable).setModificationDate(new Date(System.currentTimeMillis()));
                }
            }
        }
    }

                                                           
    protected User currentUser() {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            Object principal = subject.getPrincipal();
            if (principal != null && (!UserAccountRealm.ANONYMOUS_USER_ACCOUNT.getPrincipals().iterator().next().equals(principal))) {
                return (User)principal;
            }
        }
        return null;
    }
}
